package com.tzbank.face.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcfs.esb.client.connector.HTTPClientConnector;
import com.dcfs.esb.security.Base64;
import com.dcfs.esb.security.Des;

public class ClientConfig {

	/**
	 * 日志
	 */
	private static Log log = LogFactory.getLog(ClientConfig.class);

	private static Properties properties = null;
	private static URL cfgFileUrl = null;
	public static final String FILEPATH = "EAI_HOME";
	private static final String ESB_CLIENT = "esb-client.properties";

	/**
	 * URL
	 */
	public static final String URL = "url";

	/**
	 * 用户名
	 */
	public static final String UID = "uid";

	/**
	 * connTimeout：建立HTTP连接的超时时间
	 */
	public static final String CONN_TIME_OUT = "connTimeout";

	/**
	 * readTimeout：等待数据响应的超时时间
	 */
	public static final String READ_TIME_OUT = "readTimeout";

	/**
	 * 3DES加密的本地密钥
	 */
	public static final byte[] DES_KEY = "bank2009besb1027security".getBytes();

	/**
	 * 安全平台IP
	 */
	public static final String SS_IP = "ss_ip";
	
	/**
	 * 安全平台端口
	 */
	public static final String SS_PORT = "ss_port";
	
	/**
	 * 安全平台超时时间
	 */
	public static final String SS_TIME = "ss_time";
	
	/**
	 * 安全平台 ZEK
	 */
	public static final String SS_KEY = "ss_key";
	
	/**
	 * 
	 * 功能 :初始化操作，加载配置信息，判断配置信息是否存在
	 */
	public static void init() {
		try {
			// 加载配置信息
			load();
			// 检查配置信息
			checkConfig();
			// 设置Http相关参数信息
			setHttConnParm();
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("初始配置信息异常", e);
			}
		}
	}

	/**
	 * 功能 :检查配置信息
	 */
	private static void checkConfig() {
		// 从配置文件中提取相关配置信息
		String uid = getLogProperty(UID);

		String url = getLogProperty(URL);
		
		String ss_ip = getLogProperty(SS_IP);
		String ss_port = getLogProperty(SS_PORT);
		String ss_key = getLogProperty(SS_KEY);

		// 判断UID是否存在
		if (uid == null || "".equals(uid.trim())) {
			if (log.isErrorEnabled()) {
				log.error("虚拟用户UID不能为空");
			}
		}
		// 判断URL是否存在
		if (url == null || "".equals(url.trim())) {
			if (log.isErrorEnabled()) {
				log.error("请求ESB的URL不能为空");
			}
		}

		// 判断ss_ip是否存在
		if (ss_ip == null || "".equals(ss_ip.trim())) {
			if (log.isErrorEnabled()) {
				log.error("请求ESB的ss_ip不能为空");
			}
		}	
		// 判断ss_port是否存在
		if (ss_port == null || "".equals(ss_port.trim())) {
			if (log.isErrorEnabled()) {
				log.error("请求ESB的ss_port不能为空");
			}
		}
		// 判断ss_zek是否存在
		if (ss_key == null || "".equals(ss_key.trim())) {
			if (log.isErrorEnabled()) {
				log.error("请求ESB的ss_key不能为空");
			}
		}

	}

	/**
	 * 功能 : 检查文件中的密码域是否已经加密
	 * 
	 * @param key
	 */
	private static void check3DES(String key) {
		byte[] temp = null;
		String value = getLogProperty(key);

		// 值不存在，直接返回
		if (value == null)
			return;

		// 如果key对应的值不以${3DES}开头的，则信息需要加密后保存到配置文件中
		if (value != null && !value.startsWith("${3DES}")) {
			// 通过3DES加密
			temp = Des.encrypt3DES(value.getBytes(), DES_KEY);
			// 经过BASE64编码后带上加密前缀
			value = "${3DES}" + Base64.encodeBase64(temp);
			// 设置回Properties中
			setLogProperty(key, value);
			// 保存回配置文件中
			saveCfgFile();
		}

	}

	/**
	 * 设置连接参数
	 */
	private static void setHttConnParm() {
		int connTimeout = 0;
		try {
			connTimeout = Integer.parseInt(getLogProperty(CONN_TIME_OUT)) * 1000;
		} catch (Exception e) {
			log.warn("警告：读取Http连接超时时间出错，默认时间为10秒");

			connTimeout = 10 * 1000;

		}
		HTTPClientConnector.getInstance().setConnTimeout(connTimeout);

		int readTimeout = 0;
		try {
			readTimeout = Integer.parseInt(getLogProperty(READ_TIME_OUT)) * 1000;
		} catch (Exception e) {
			readTimeout = 120 * 1000;
			log.warn("警告：读取Http响应超时时间出错，默认时间为120秒");
		}
		HTTPClientConnector.getInstance().setReadTimeout(readTimeout);

		String url = getLogProperty(URL);
		if (url != null)
			HTTPClientConnector.getInstance().setHttpUrl(url);
		else
			log.error("读取Http的URL出错，请确认HTTP的URL无误");
	}

	/**
	 * 功能：加载配置文件
	 */
	private static void load() {
		try {
			// 初始配置文件的URL为空
			cfgFileUrl = null;

			// 通过环境变量获取配置文件
			String filePath = System.getProperty(FILEPATH);
			filePath = "/config";
			if (filePath != null && !"".equals(filePath)) {
				if (log.isDebugEnabled()) {
					log.debug("通过环境变量获取配置信息");
				}
				File cfgFile = new File(filePath + "/" + ESB_CLIENT);
				if (cfgFile.exists()) {
					cfgFileUrl = cfgFile.toURL();
				} else {
					if (log.isErrorEnabled()) {
						log.error(filePath + "配置文件不存在");
					}
				}
			}

			// 配置文件不存在，尝试通过当前类加载器加载配置文件
			if (cfgFileUrl == null) {
				if (log.isDebugEnabled()) {
					log.debug("尝试通过当前类加载器加载配置信息");
				}
				cfgFileUrl = ClientConfig.class.getResource("/" + ESB_CLIENT);
			}

			// 配置文件不存在，尝试通过系统类加载器加载配置文件
			if (cfgFileUrl == null) {
				if (log.isDebugEnabled()) {
					log.debug("尝试通过系统类加载器加载配置信息");
				}
				cfgFileUrl = System.class.getResource(ESB_CLIENT);
			}
			//配置文件在jar包中，通过流的方式直接读取jar包中的配置文件，配置文件通过EAI
			// 加载配置信息
			properties = new Properties();
			if (cfgFileUrl != null) {
				properties.load(cfgFileUrl.openStream());
			} else {
				InputStream is = ClientConfig.class.getResourceAsStream(filePath+"/"+ESB_CLIENT);
				BufferedReader bf = new BufferedReader(new InputStreamReader(is));
				properties.load(bf);
				if (log.isErrorEnabled()) {
					log.error(ESB_CLIENT + "配置文件不存在，系统初始化失败！");
				}
			}

			if (log.isInfoEnabled()) {
				log.info("加载配置信息成功");
			}
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("加载配置信息失败", e);
			}
		}

	}

	/**
	 * 功能：保存配置文件
	 */
	public static void saveCfgFile() {
		try {
			if (cfgFileUrl != null && properties != null) {
				String fileName = URLDecoder.decode(cfgFileUrl.getPath(),
						"UTF-8");
				FileOutputStream fos = new FileOutputStream(fileName);
				properties.store(fos, "encrypt masterKey or masterkey");
				fos.close();
				if (log.isInfoEnabled())
					log.info("保存配置文件成功");
			}
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("将密钥保存到配置文件出错，存在安全隐患，但不影响交易", e);
			}
		}
	}

	/**
	 * 程序设置初始化日志属性
	 */
	public static void load(Properties prop) {
		// 加载prop信息
		properties = prop;
		// 检查配置信息
		checkConfig();
		// 设置Http相关参数信息
		setHttConnParm();
	}

	/**
	 * 功能：根据key获取对应的值
	 * 
	 * @param key
	 * @return
	 */
	public static String getLogProperty(String key) {
		String property = properties.getProperty(key);
		return property;
	}

	/**
	 * 功能：获得URL
	 * 
	 * @return
	 */
	public static String getUrl() {
		String url = properties.getProperty(URL);
		return url;
	}

	/**
	 * 功能：根据属性名获取属性值
	 * 
	 * @param propertyName
	 * @return
	 */
	public static void setLogProperty(String propertyName, String value) {
		properties.setProperty(propertyName, value);
	}
	
	public static void main(String[] args) {
		ClientConfig.init();
		System.out.println(properties.get("url"));
	}
}